package org.hairball.viewer.jung;


import edu.uci.ics.jung.graph.Vertex;
import edu.uci.ics.jung.graph.impl.SparseGraph;
import edu.uci.ics.jung.graph.impl.SparseVertex;
import edu.uci.ics.jung.graph.impl.UndirectedSparseEdge;
import edu.uci.ics.jung.utils.UserDataContainer;
import org.hairball.AnalysisType;
import org.hairball.ClassInclusionFilter;
import org.hairball.HairballGraphFactory;
import org.hairball.graph.EdgeVisitor;
import org.hairball.graph.HairballGraph;
import org.hairball.graph.NodeVisitor;

import java.io.IOException;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

public class JungGraphFactory {
    public SparseGraph createGraph(String jarFileLocation) throws IOException {
        ClassInclusionFilter inclusionFilter = new ClassInclusionFilter() {

            public boolean shouldInclude(String fullyQualifiedClassName) {
                return true;
            }
        };

        Set<AnalysisType> analysisTypes = new HashSet<AnalysisType>();
        analysisTypes.add(AnalysisType.CONSTRUCTOR_INJECTION);
        analysisTypes.add(AnalysisType.SETTER_INJECTION);

        HairballGraph hairballGraph = new HairballGraphFactory().create(inclusionFilter, analysisTypes, jarFileLocation);

        final SparseGraph graph = new SparseGraph();

        final Map<String, Vertex> verticies = new HashMap<String, Vertex>();
        hairballGraph.visitNodes(new NodeVisitor() {
            public void visit(String node, boolean connected) {
                SparseVertex vertex = new SparseVertex();
                graph.addVertex(vertex);
                vertex.setUserDatum("NAME", node, new UserDataContainer.CopyAction() {

                    public Object onCopy(Object object, UserDataContainer userDataContainer, UserDataContainer userDataContainer1) {
                        return object;
                    }
                });
                verticies.put(node, vertex);
            }
        });

        hairballGraph.visitEdges(new EdgeVisitor() {

            public void visit(String fromNode, String toNode, String edgeType) {
                UndirectedSparseEdge edge = new UndirectedSparseEdge(verticies.get(fromNode), verticies.get(toNode));
                edge.setUserDatum("NAME", edgeType, new UserDataContainer.CopyAction() {

                    public Object onCopy(Object object, UserDataContainer userDataContainer, UserDataContainer userDataContainer1) {
                        return object;
                    }
                });
                graph.addEdge(edge);
            }
        });

        return graph;
    }
}
